package tt.dz.biz.service.rpc;

import com.alibaba.fastjson.JSONObject;
import javax.annotation.Resource;
import org.apache.avro.Protocol;
import org.apache.avro.Protocol.Message;
import org.apache.avro.generic.GenericRecord;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import tt.dz.biz.dao.user.UserDAOImpl;
import tt.dz.biz.dao.verifycode.MsVerifyCodeDAOImp;
import tt.dz.biz.service.user.OperListService;
import tt.dz.common.BusinessException;
import tt.dz.common.DZStringUtil;
import tt.dz.common.DzDigester;
import tt.dz.common.DzErrorCode;
import tt.dz.common.DzErrorCode.CommonErrorCode;
import tt.dz.common.DzErrorCode.ExceptionErrorCode;
import tt.dz.common.DzErrorCode.UserErrorCode;
import tt.dz.common.RPCUtil;
import tt.dz.vo.UserBaseVO;
import tt.dz.vo.VerifyCodeVO;
import tt.dz.vo.request.BaseRpcRequestVo;
import tt.dz.vo.request.ResetPasswordRpcRequestVo;
import tt.dz.vo.request.ResetPasswordRpcRequestVo.RestPwdType;

@Service("rpcResetPwdService")
public class RPCResetPwdService
  implements RPCBaseService
{
  private static Logger log = LoggerFactory.getLogger(RPCResetPwdService.class);
  @Resource(name="operListService")
  private OperListService operListService;
  @Resource(name="msVerifyCodeDAO")
  private MsVerifyCodeDAOImp msVerifyCodeDAO;
  @Resource(name="userDAO")
  private UserDAOImpl userDao;
  
  public Object execute(Protocol.Message message, Object request, Protocol protocol)
    throws Exception
  {
    JSONObject resultJson = null;
    try
    {
      String requestStr = ((GenericRecord)request).get("req").toString();
      ResetPasswordRpcRequestVo vo = (ResetPasswordRpcRequestVo)BaseRpcRequestVo.convertAndValidateVo(requestStr, ResetPasswordRpcRequestVo.class);
      ResetPasswordRpcRequestVo.RestPwdType type = ResetPasswordRpcRequestVo.RestPwdType.indexOf(vo.getType());
      String newPasswod = vo.getPassword();
      UserBaseVO userBaseVo = getUserBase(vo);
      if (null == userBaseVo)
      {
        DzErrorCode.UserErrorCode e = DzErrorCode.UserErrorCode.USER_NOT_FOUND;
        throw new BusinessException(e.value(), e.getDesc(), "当前查询用户不存在");
      }
      switch ( type.ordinal())
      {
      case 1: 
        break;
      case 2: 
        validateCheckCode(vo);
        break;
      case 3: 
        validateOldPasswod(userBaseVo, vo);
        break;
      default: 
        DzErrorCode.CommonErrorCode e = DzErrorCode.CommonErrorCode.FORMAT_ERROR;
        throw new BusinessException(e.value(), e.getDesc(), "当前不存在此重置方法");
      }
      String salt = DZStringUtil.getRandomString(6);
      userBaseVo.setPassword(DzDigester.md5ForUser(newPasswod, salt));
      userBaseVo.setSalt(salt);
      this.userDao.updateUserByBase(userBaseVo);
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(1), "", "");
    }
    catch (BusinessException e)
    {
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(0), e.getStatusCode(), e.getStatusDescribe());
    }
    catch (Exception e)
    {
      DzErrorCode.ExceptionErrorCode ec = DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION;
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(0), ec.value(), ec.getDesc());
    }
    return resultJson.toJSONString();
  }
  
  private void validateOldPasswod(UserBaseVO userBaseVo, ResetPasswordRpcRequestVo vo)
    throws BusinessException
  {
    String oldDbSalt = userBaseVo.getSalt();
    String oldDbPassword = userBaseVo.getPassword();
    String oldRequestPassword = vo.getOldPassword();
    if ((null == oldDbSalt) || (null == oldDbPassword))
    {
      DzErrorCode.CommonErrorCode e = DzErrorCode.CommonErrorCode.PARAM_FORMAT_ERROR;
      throw new BusinessException(e.value(), e.getDesc(), "当前系统原始密码为null");
    }
    String expectPasswod = DzDigester.md5ForUser(oldRequestPassword, oldDbSalt);
    if (!oldDbPassword.trim().equals(expectPasswod))
    {
      DzErrorCode.UserErrorCode e = DzErrorCode.UserErrorCode.BAD_PWD;
      throw new BusinessException(e.value(), e.getDesc(), "当前原始密码不匹配");
    }
  }
  
  private void validateCheckCode(ResetPasswordRpcRequestVo vo)
    throws BusinessException
  {
    String mobileNo = vo.getMobileNo();
    String checkCode = vo.getCheckCode();
    VerifyCodeVO verifyCodeVO = this.msVerifyCodeDAO.getVerifyCodeByPhone(mobileNo);
    DzErrorCode.UserErrorCode e = null;
    if (verifyCodeVO != null)
    {
      String content = verifyCodeVO.getContent();
      if (!StringUtils.equals(checkCode, content))
      {
        e = DzErrorCode.UserErrorCode.BAD_SMS_CODE;
        throw new BusinessException(e.value(), e.getDesc(), "当前验证码错误");
      }
    }
    else
    {
      e = DzErrorCode.UserErrorCode.NOT_SEND_SMS_CODE;
      throw new BusinessException(e.value(), e.getDesc(), "手机未发验证码");
    }
  }
  
  private UserBaseVO getUserBase(ResetPasswordRpcRequestVo vo)
  {
    String mobileNo = vo.getMobileNo();
    String merchantCode = vo.getMerchantCode();
    return this.userDao.getUserBaseByUserId(null, mobileNo, merchantCode);
  }
}
